﻿// 为了方便管理，就将[Code]区段单独拿出来了
// innosetup 支持的颜色值
// clBlack（黑色），clMaroon（暗红），clGreen（绿色），clOlive（橄榄绿），
// clNavy（深蓝），clPurple（紫色），clTeal（深青），clGray（灰色），
// clSilver（浅灰），clRed（红色），clLime（浅绿），clYellow（黄色），
// clBlue （蓝色），clFuchsia（紫红），clAqua（青绿），clWhite（白色）。
// 引入botva2的函数声明
#include ".\botva2.iss"
//#include ".\DllsImport.iss"

[Code]
const PRODUCT_REGISTRY_KEY = 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{#MyAppID}_is1';
const WM_SYSCOMMAND = $0112;
const ID_BUTTON_ON_CLICK_EVENT = 1;
const CS_DROPSHADOW = 131072;
const GCL_STYLE = -26;

// UI 设置
const WIZARDFORM_WIDTH_NORMAL = 660;
const WIZARDFORM_HEIGHT_NORMAL = 480;
const WIZARDFORM_HEIGHT_MORE = 600;
const WIZARDFORM_BORDER_WIDTH = 1;
const CUSTOMFORM_WIDTH_NORMAL = 400;
const CUSTOMFORM_HEIGHT_NORMAL = 154;

// 自定义UI
var mainBkPanel:TPanel;								    // 主窗口背景
var label_wizardform_main:TLabel;			    // 主界面背景点击相应
var button_minimize:HWND; 							  // 最小化按钮
var button_close:HWND; 								    // 关闭按钮
var versionBk:TLabel;										  // 版本背景
var label_version:TLabel;						      // version number
var button_install_now:HWND;				      // 立马安装
var button_install_now_font: TFont;       // 立马按照按钮字体

var label_error_tips:TLabel;				      // 安装tips: 1.路径无效？ 2.内存不足？

//许可证复选框数据
var checkbox_license: HWND;				        // license checkbox
var label_agree_title: TLabel; 		        // agree title
var label_agree_content: TLabel; 	        // 条款

//更多选择按钮数据
var button_customize_setup: HWND;				  // 更多选择按钮 
var button_customize_setup_font: TFont;   // 更多选择的文本
var button_uncustomize_setup: HWND;			  // 自定义展开		

var label_need_space:TLabel;							// 需要的空间label
var label_disk_space:TLabel;							// 磁盘的空间label	
var edit_target_path : TEdit;							// 路径选择
var button_browse:HWND;										// 浏览
var label_warn_tips:TLabel;								// warning的tips

var label_install_progress : TLabel;      // 进度条
var button_run_now:HWND;							    // 立马安装

// messagebox 
var messagebox_close : TSetupForm;
var closeBkPanel:TPanel;									// messagebox
var image_message_background: LONGINT;
var label_messagebox_main: TLabel;
var label_messagebox_information: TLabel;
var button_messagebox_ok: HWND;
var button_messagebox_yes: HWND;
var button_messagebox_no: HWND;
var button_messagebox_continue: HWND;
var button_messagebox_teminate: HWND;
	  
// custom var 
var image_wizardform_background: LONGINT;
var image_version_background: LONGINT;
var dNeedSpaceByte:Int64; 								  // 需要的安装的空间大小，（字节)
var image_progressbar_background: LONGINT;
var image_progressbar_foreground: LONGINT;
var can_exit_setup: BOOLEAN;
var can_next_setup: BOOLEAN;
Var
  PBOldProc : LONGINT;
  button_messagebox_cancel : HWND;
  isFirst, is_wizardform_show_normal, is_installer_initialized, is_platform_windows_7, is_wizardform_released: BOOLEAN;
  version_installed_before : STRING;
  
var
  UninstallFirstPage: TNewNotebookPage;
  UninstallSecondPage: TNewNotebookPage;
  UninstallBackButton: TNewButton;
  UninstallNextButton: TNewButton;

// 磁盘控件相关
procedure TconSetVisible(lbl:TControl; bVis:BOOLEAN);
begin
  if bVis then
    begin 
     lbl.Show;
   end 
  else 
    begin 
     lbl.Hide;
	end;
end;

// check path

function PathCharLength(const S: String; const Index: Integer): Integer;
{ Returns the length in bytes of the character at Index in S.
  Notes:
  1. If Index specifies the last character in S, 1 will always be returned,
     even if the last character is a lead byte.
  2. If a lead byte is followed by a null character (e.g. #131#0), 2 will be
     returned. This mimics the behavior of MultiByteToWideChar and CharPrev,
     but not CharNext(P)-P, which would stop on the null. }
begin
  {$IFNDEF UNICODE}
  if IsDBCSLeadByte(Ord(S[Index])) and (Index < Length(S)) then
    Result := 2
  else
  {$ENDIF}
    Result := 1;
end;

function PathNormalizeSlashes(const S: String): String;
{ Returns S minus any superfluous slashes, and with any forward slashes
  converted to backslashes. For example, if S is 'C:\\\some//path', it returns
  'C:\some\path'. Does not remove a double backslash at the beginning of the
  string, since that signifies a UNC path. }
var
  Len, temp, number, index: Integer;
begin
  Result := S;
  Len := Length(Result);
  index := 1;
  while index <= Len do begin
    if Result[index] = '/' then
      Result[index] := '\';
      number := PathCharLength(Result, index);
      temp := index;
      index := temp + number;
  end;
  index := 1;
  while index < Length(Result) do begin
    if (Result[index] = '\') and (Result[index+1] = '\') and (index > 1) then
      Delete(Result, index+1, 1)
    else
      number := PathCharLength(Result, index);
      temp := index;
      index := temp + number;
  end;
end;

procedure TidyUpDirName(var Path: String);
{ Tidies up a directory name }
begin
  { Trim spaces, normalize slashes, remove any trailing backslash, then repeat
    the process if necessary (e.g. in the 'C:\Program Files\My Program\ \'
    case) }
  repeat
    Path := RemoveBackslashUnlessRoot(PathNormalizeSlashes(Trim(Path)));
  until Length(Path) = Length(Trim(Path));
end;

type
  TSysCharSet = set of AnsiChar;
function CharInSet(C: AnsiChar; const CharSet: TSysCharSet): Boolean;
begin
  Result := C in CharSet;
end;

function ValidateCustomDirEdit(const inputPath: String): Boolean;
{ Checks if AEdit.Text contains a valid-looking pathname, and returns True
  if so. May alter AEdit.Text to remove redundant spaces and backslashes. }
var
  IsUNCPath: Boolean;
  driveType: Integer;
begin
  Result := False;
  TidyUpDirName(inputPath);

  { Check if the path is too long.
    Note: There's no sense in allowing paths to be as long as MAX_PATH (260)
    since there wouldn't be any room left to append a filename. 240 should be
    a reasonable limit. }
  if Length(inputPath) > 240 then begin
    Exit;
  end;

  { Check for UNC pathname }
  IsUNCPath := (Length(inputPath) >= 2) and (inputPath[1] = '\') and (inputPath[2] = '\');
  if IsUNCPath then begin
    Exit;
  end;

  if(PathIsNetworkPath(inputPath)) then begin
    EXIT;
  end;

  driveType := GetDriveType(inputPath);
  if (driveType = 2) or (driveType = 4) then begin
    Exit;
  end;

  Result := True;
end;

function Misc_FomatByteText(const I: Int64):string;
var
  X: Extended;  
begin
  if I > 1073741824 then 
  begin 
    X := (I*1.0 / 1073741824) * 100;
    X := X / 100;
    Result := Format('%.2f GB', [X]);
	Exit;
  end;
  
  if I > 1048576 then 
  begin
    X := (I*1.0 / 1048576) * 10;
    X := X / 10;
    Result := Format('%.1f MB', [X]);
	Exit;
  end;
  
  if I > 1024 then 
  begin
    X := I*1.0 / 1024;
    Result := Format('%.0f KB', [X]);
	Exit;
  end;
  Result := Format('%d B', [I]);
end;

function GetNeedSpaceText():string;
var 
  iv:string;
begin 
  iv:= Misc_FomatByteText(dNeedSpaceByte);
  result:=format('Installation Path: Required：%s',[iv]);
end;

function GetCurDirFreeSpace():Cardinal;
var
 curPath:string;
 FreeSpace,TotalSpace:Cardinal;
begin
  curPath := edit_target_path.Text;
  GetSpaceOnDisk(ExtractFileDrive(curPath),True,FreeSpace,TotalSpace);
  result := FreeSpace;
end;

function GetDiskSpaceText(FreeSpace:Cardinal):string;
var 
  iv:string;
begin 
  
  if FreeSpace > 1024 then 
  begin iv := Format('%.0f GB',[FreeSpace/1024.0 ]) ; 
  end
  else 
  begin iv := Format('%d MB',[FreeSpace]);
  end;
  result:=format('Available：%s',[iv]);
end;

procedure WhenInstallDirChangeCheckDiskSpace();
var FreeSpace: Cardinal;
var errorDir: AnsiString;
var driveType: Integer;
begin
  FreeSpace := GetCurDirFreeSpace();
  label_need_space.Caption := GetNeedSpaceText();
  label_disk_space.Caption := GetDiskSpaceText(FreeSpace);
  driveType := GetDriveType(edit_target_path.Text);
  
  if not ValidateCustomDirEdit(edit_target_path.Text) then
  begin
    label_warn_tips.Caption := 'The installation path is invalid!'
    TconSetVisible(label_warn_tips, TRUE);
    BtnSetEnabled(button_install_now, FALSE);
    Exit;
  end;

  if (FreeSpace <= (dNeedSpaceByte / 1024 / 1024)) then
  begin
    label_warn_tips.Caption := 'The disk space selected is less than the space required by the application!'
    TconSetVisible(label_warn_tips, TRUE);
    BtnSetEnabled(button_install_now, FALSE);
    Exit;
  end;

	label_warn_tips.Caption := ''
	TconSetVisible(label_warn_tips, FALSE);
  if BtnGetChecked(checkbox_license) then
  begin
    BtnSetEnabled(button_install_now, TRUE);
  end else
  begin 
    BtnSetEnabled(button_install_now, FALSE);
  end;
end;

//主界面浏览按钮按下时执行的脚本
PROCEDURE button_browse_on_click(hBtn : HWND);
BEGIN
  WizardForm.DirBrowseButton.OnClick(WizardForm);
  edit_target_path.Text := WizardForm.DirEdit.Text;
  WhenInstallDirChangeCheckDiskSpace();
END;

//路径输入框文本变化时执行的脚本
PROCEDURE edit_target_path_on_change(Sender : TObject);
BEGIN
  WizardForm.DirEdit.Text := edit_target_path.Text;
  WhenInstallDirChangeCheckDiskSpace();
END;

//主界面关闭按钮按下时执行的脚本
PROCEDURE button_close_on_click(hBtn : HWND);
BEGIN
  WizardForm.CancelButton.OnClick(WizardForm);
END;

//主界面最小化按钮按下时执行的脚本
PROCEDURE button_minimize_on_click(hBtn : HWND);
BEGIN
  SendMessage(WizardForm.Handle, WM_SYSCOMMAND, 61472, 0);
END;

//主界面自定义安装按钮按下时执行的脚本
PROCEDURE button_customize_setup_on_click(hBtn : HWND);
BEGIN
  IF is_wizardform_show_normal THEN
  BEGIN
  WhenInstallDirChangeCheckDiskSpace();
	mainBkPanel.Height := WIZARDFORM_HEIGHT_MORE - WIZARDFORM_BORDER_WIDTH * 2;
    WizardForm.Height := WIZARDFORM_HEIGHT_MORE;
    edit_target_path.Show();
    BtnSetVisibility(button_browse, TRUE);
    BtnSetVisibility(button_customize_setup, FALSE);
    BtnSetVisibility(button_uncustomize_setup, TRUE);
    is_wizardform_show_normal := FALSE;
  END ELSE
  BEGIN
    edit_target_path.Hide();
    label_error_tips.Hide();
    BtnSetVisibility(button_browse, FALSE);
	mainBkPanel.Height := WIZARDFORM_HEIGHT_NORMAL - WIZARDFORM_BORDER_WIDTH * 2;
    WizardForm.Height := WIZARDFORM_HEIGHT_NORMAL;
    BtnSetVisibility(button_customize_setup, TRUE);
    BtnSetVisibility(button_uncustomize_setup, FALSE);
    is_wizardform_show_normal := TRUE;
  END;
  ImgApplyChanges(mainBkPanel.Handle);
  ImgApplyChanges(WizardForm.Handle);
END;

//同意许可协议的复选框被点击时执行的脚本
PROCEDURE checkbox_license_on_click(hBtn : HWND);
BEGIN
    if BtnGetChecked(checkbox_license) and not label_warn_tips.Visible then
    begin
      BtnSetEnabled(button_install_now, TRUE);
    end else
    begin
      BtnSetEnabled(button_install_now, FALSE);
    end;
END;

//释放安装程序时调用的脚本
PROCEDURE release_installer();
BEGIN
  gdipShutdown();
  messagebox_close.Release();
  WizardForm.Release();
END;

function IsAppRunning(FileName : string): Boolean;
var
    FSWbemLocator: Variant;
    FWMIService   : Variant;
    FWbemObjectSet: Variant;
begin
    Result := false;
    FSWbemLocator := CreateOleObject('WBEMScripting.SWBEMLocator');
    FWMIService := FSWbemLocator.ConnectServer('', 'root\CIMV2', '', '');
    FWbemObjectSet := FWMIService.ExecQuery(Format('SELECT Name FROM Win32_Process Where Name="%s"',[FileName]));
    Result := (FWbemObjectSet.Count > 0);
    FWbemObjectSet := Unassigned;
    FWMIService := Unassigned;
    FSWbemLocator := Unassigned;
end;

function DirExists(const Name: String): Boolean;
{ Returns True if the specified directory name exists. The specified name
  may include a trailing backslash.
  NOTE: Delphi's FileCtrl unit has a similar function called DirectoryExists.
  However, the implementation is different between Delphi 1 and 2. (Delphi 1
  does not count hidden or system directories as existing.) }
var
  Attr: Integer;
begin
  Attr := GetFileAttributes(Name);
  Result := (Attr <> -1) and (Attr and 16 <> 0);
end;


//messagebox pop 1:close program 2:install path exists 3.program have install 4.app is running
PROCEDURE MessageboxShowModal(msgType: INTEGER);
BEGIN
	IF (msgType = 1) THEN
	BEGIN
		label_messagebox_information.Caption := 'Stop installing Anycubic Photon Workshop now?'
		BtnSetVisibility(button_messagebox_continue, TRUE);
		BtnSetVisibility(button_messagebox_teminate, TRUE);
		BtnSetVisibility(button_messagebox_ok, FALSE);
		BtnSetVisibility(button_messagebox_yes, FALSE);
		BtnSetVisibility(button_messagebox_no, FALSE);
	END ELSE IF (msgType = 2) THEN
	BEGIN
		label_messagebox_information.Caption := 'The installation path already exists.would you like to install to that folder anyway?'
		BtnSetVisibility(button_messagebox_continue, FALSE);
		BtnSetVisibility(button_messagebox_teminate, FALSE);
		BtnSetVisibility(button_messagebox_ok, FALSE);
		BtnSetVisibility(button_messagebox_yes, TRUE);
		BtnSetVisibility(button_messagebox_no, TRUE);
	END ELSE IF (msgType = 3) THEN
	BEGIN
		label_messagebox_information.Caption := 'You’ve installed Anycubic Photon Workshop in your system. Do you want to cover it?'
		BtnSetVisibility(button_messagebox_continue, FALSE);
		BtnSetVisibility(button_messagebox_teminate, FALSE);
		BtnSetVisibility(button_messagebox_ok, FALSE);
		BtnSetVisibility(button_messagebox_yes, TRUE);
		BtnSetVisibility(button_messagebox_no, TRUE);
	END ELSE IF (msgType = 4) THEN
	BEGIN
		label_messagebox_information.Caption := 'You’re using Anycubic Photon Workshop, Please close it and try again.'
		BtnSetVisibility(button_messagebox_continue, FALSE);
		BtnSetVisibility(button_messagebox_teminate, FALSE);
		BtnSetVisibility(button_messagebox_ok, TRUE);
		BtnSetVisibility(button_messagebox_yes, FALSE);
		BtnSetVisibility(button_messagebox_no, FALSE);
	END;

    messagebox_close.Left := WizardForm.Left + (WIZARDFORM_WIDTH_NORMAL - CUSTOMFORM_WIDTH_NORMAL) / 2;
	messagebox_close.top := WizardForm.Top + (WIZARDFORM_HEIGHT_NORMAL - CUSTOMFORM_HEIGHT_NORMAL) / 2;
	messagebox_close.ShowModal();
END;

//主界面安装按钮按下时执行的脚本
PROCEDURE install_right_now_on_click(hBtn : HWND);
var
  resultCode: Boolean;
  uicmd:String;
BEGIN
  resultCode := IsAppRunning(ExpandConstant('{#MyAppExeName}'));
	if resultCode then
	begin
      MessageboxShowModal(4)
	end else
  if RegQueryStringValue(HKEY_LOCAL_MACHINE, 
                           PRODUCT_REGISTRY_KEY,
                           'UninstallString', 
                           uicmd) then
  begin
    MessageboxShowModal(3)
    if(can_next_setup) then
      begin
        WizardForm.NextButton.OnClick(WizardForm);
      end;
  end else 
  if DirExists(WizardForm.DirEdit.Text) then
  begin
    MessageboxShowModal(2)
    if(can_next_setup) then
      begin
        WizardForm.NextButton.OnClick(WizardForm);
      end;
  end else
  begin
    WizardForm.NextButton.OnClick(WizardForm);
  end;
END;

//重载主界面取消按钮被按下后的处理过程
PROCEDURE CancelButtonClick(CurPageID : INTEGER; VAR Cancel, Confirm: BOOLEAN);
BEGIN
	Confirm := FALSE;
	MessageboxShowModal(1)
	IF can_exit_setup THEN
	BEGIN
		Cancel := TRUE;
	END ELSE
	BEGIN
		Cancel := FALSE;
	END;
END;

PROCEDURE button_messagebox_ok_on_click(hBtn : HWND);
BEGIN
	can_exit_setup := True;
	messagebox_close.Close();
	WizardForm.Close();
END;

PROCEDURE button_messagebox_yes_on_click(hBtn : HWND);
BEGIN
	messagebox_close.Close();
	can_next_setup := True;
END;

PROCEDURE button_messagebox_no_on_click(hBtn : HWND);
BEGIN
	messagebox_close.Close();
	can_next_setup := False;
END;

PROCEDURE button_messagebox_continue_on_click(hBtn : HWND);
BEGIN
	messagebox_close.Close();
	can_exit_setup := False;
END;

PROCEDURE button_messagebox_teminate_on_click(hBtn : HWND);
BEGIN
	messagebox_close.Close();
	WizardForm.Close();
	can_exit_setup := True;
END;

//主界面安装按钮按下时执行的脚本
PROCEDURE run_now_on_click(hBtn : HWND);
BEGIN 
  WizardForm.NextButton.OnClick(WizardForm);
END;

//复制文件时执行的脚本，每复制1%都会被调用一次，若要调整进度条或进度提示请在此段修改
FUNCTION PBProc(h : hWnd; Msg, wParam, lParam : LONGINT) : LONGINT;
VAR
  pr, i1, i2 : EXTENDED;
  w : INTEGER;
BEGIN
  Result := CallWindowProc(PBOldProc, h, Msg, wParam, lParam);
  IF ((Msg = $402) AND (WizardForm.ProgressGauge.Position > WizardForm.ProgressGauge.Min)) THEN
  BEGIN
    i1 := WizardForm.ProgressGauge.Position - WizardForm.ProgressGauge.Min;
    i2 := WizardForm.ProgressGauge.Max - WizardForm.ProgressGauge.Min;
    pr := (i1 * 100) / i2;
    label_install_progress.Caption := Format('Installing... %d', [Round(pr)]) + '%';
    w := Round((550 * pr) / 100);
    ImgSetPosition(image_progressbar_foreground, 55, 315, w, 4);
    ImgSetVisiblePart(image_progressbar_foreground, 0, 0, w, 4);
	ImgApplyChanges(mainBkPanel.Handle);
  END;
END;

//阅读许可协议的按钮按下时执行的脚本
PROCEDURE button_license_on_click(Sender : TObject; Button : TMouseButton; Shift : TShiftState; X, Y : INTEGER);
VAR
  ErrorCode : INTEGER;
BEGIN
 ReleaseCapture();
  ShellExec('', '{#MyAppLicenseURL}', '', '', SW_SHOW, ewNoWait, ErrorCode);
END;

//取消安装弹框的取消按钮按下时执行的脚本
PROCEDURE button_messagebox_cancel_on_click(hBtn : HWND);
BEGIN
  messagebox_close.Close();
END;

//主界面被点住就随鼠标移动的脚本
PROCEDURE wizardform_on_mouse_down(Sender : TObject; Button : TMouseButton; Shift : TShiftState; X, Y : INTEGER);
BEGIN
  ReleaseCapture();
  SendMessage(WizardForm.Handle, WM_SYSCOMMAND, $F012, 0);
END;

//取消弹框被点住就随鼠标移动的脚本
PROCEDURE messagebox_on_mouse_down(Sender : TObject; Button : TMouseButton; Shift : TShiftState; X, Y : INTEGER);
BEGIN
  ReleaseCapture();
  SendMessage(messagebox_close.Handle, WM_SYSCOMMAND, $F012, 0);
END;

//判断系统是否为Win7，是则返回TRUE，否则返回FALSE
PROCEDURE determine_wether_is_windows_7_or_not();
VAR
  sysVersion : TWindowsVersion;
BEGIN
  GetWindowsVersionEx(sysVersion);
  IF sysVersion.NTPlatform AND (sysVersion.Major = 6) AND (sysVersion.Minor = 1) THEN
  BEGIN
    is_platform_windows_7 := TRUE;
  END ELSE
  BEGIN
    is_platform_windows_7 := FALSE;
  END;
END;

//创建取消弹框的脚本
PROCEDURE messagebox_close_create();
BEGIN
  messagebox_close := CreateCustomForm();
  WITH messagebox_close DO
  BEGIN
    BorderStyle := bsNone;
	Left := WizardForm.Left + (WIZARDFORM_WIDTH_NORMAL - CUSTOMFORM_WIDTH_NORMAL) / 2;
	Top := WizardForm.Top + (WIZARDFORM_HEIGHT_NORMAL - CUSTOMFORM_HEIGHT_NORMAL) / 2;
    Width := CUSTOMFORM_WIDTH_NORMAL;
    Height := CUSTOMFORM_HEIGHT_NORMAL;
    Color := $FCD6BD;
    Caption := '';
  END;
          // 16777215
  //SetWindowLong(messagebox_close.Handle, -20, GetWindowLong(messagebox_close.Handle, -20) or 524288);
  //SetLayered(messagebox_close.Handle, $FFFFFFFF, 255, 1 or 2);
  //SetLayered(messagebox_close.Handle, $FF0000, 255, 2);
	
  closeBkPanel := TPanel.Create(messagebox_close);
  WITH closeBkPanel DO
  BEGIN
    Parent := messagebox_close;
    Top := WIZARDFORM_BORDER_WIDTH;
    Left := WIZARDFORM_BORDER_WIDTH;
    BorderStyle := bsNone
    Width := CUSTOMFORM_WIDTH_NORMAL - WIZARDFORM_BORDER_WIDTH * 2;
    Height := CUSTOMFORM_HEIGHT_NORMAL - WIZARDFORM_BORDER_WIDTH * 2;
    BevelKind := bkNone;
    BevelInner := bvNone;
    BevelOuter := bvNone;
    Visible := True;                        
    image_message_background := ImgLoad(closeBkPanel.Handle, ExpandConstant('{tmp}\messagebox_bk.png'), 0, 0, 380, 190, FALSE, TRUE);
  END;
 
  label_messagebox_information := TLabel.Create(closeBkPanel);
  WITH label_messagebox_information DO
  BEGIN
    Parent := closeBkPanel;
    AutoSize := FALSE;
    Left := 20;
    Top := 24;
    Width := 360;
    Height := 70;
    Font.Name := 'Microsoft YaHei';
    Font.Size := 10;
    Font.Color := $333333;
    Caption := '';
    Transparent := TRUE;
    WordWrap := TRUE;
    OnMouseDown := @messagebox_on_mouse_down;
  END;
  label_messagebox_main := TLabel.Create(closeBkPanel);
  WITH label_messagebox_main DO
  BEGIN
    Parent := closeBkPanel;
    AutoSize := FALSE;
    Left := 0;
    Top := 0;
    Width := closeBkPanel.Width;
    Height := closeBkPanel.Height;
    Caption := '';
    Transparent := TRUE;
    //BtnSetEvent(label_messagebox_main, ID_BUTTON_ON_CLICK_EVENT, WrapBtnCallback(@button_messagebox_cancel_on_click, 1));
    OnMouseDown := @messagebox_on_mouse_down;
  END;
  
  // ok
  button_messagebox_ok := BtnCreate(closeBkPanel.Handle, 152, 102, 96, 28, ExpandConstant('{tmp}\button_ok.png'), 0, FALSE);
  BtnSetEvent(button_messagebox_ok, ID_BUTTON_ON_CLICK_EVENT, WrapBtnCallback(@button_messagebox_ok_on_click, 1));
  BtnSetVisibility(button_messagebox_ok, FALSE);
  
  // yes/no 
  button_messagebox_yes := BtnCreate(closeBkPanel.Handle, 96, 102, 96, 28, ExpandConstant('{tmp}\button_yes.png'), 0, FALSE);
  BtnSetEvent(button_messagebox_yes, ID_BUTTON_ON_CLICK_EVENT, WrapBtnCallback(@button_messagebox_yes_on_click, 1));
  BtnSetVisibility(button_messagebox_yes, FALSE);
  button_messagebox_no := BtnCreate(closeBkPanel.Handle, 208, 102, 96, 28, ExpandConstant('{tmp}\button_no.png'), 0, FALSE);
  BtnSetEvent(button_messagebox_no, ID_BUTTON_ON_CLICK_EVENT, WrapBtnCallback(@button_messagebox_no_on_click, 1));
  BtnSetVisibility(button_messagebox_no, FALSE);

  // continue/Teminate 
  button_messagebox_continue := BtnCreate(closeBkPanel.Handle, 96, 102, 96, 28, ExpandConstant('{tmp}\button_continue.png'), 0, FALSE);
  BtnSetEvent(button_messagebox_continue, ID_BUTTON_ON_CLICK_EVENT, WrapBtnCallback(@button_messagebox_continue_on_click, 1));
  BtnSetVisibility(button_messagebox_continue, FALSE);
  button_messagebox_teminate := BtnCreate(closeBkPanel.Handle, 208, 102, 96, 28, ExpandConstant('{tmp}\button_teminate.png'), 0, FALSE);
  BtnSetEvent(button_messagebox_teminate, ID_BUTTON_ON_CLICK_EVENT, WrapBtnCallback(@button_messagebox_teminate_on_click, 1));
  BtnSetVisibility(button_messagebox_teminate, FALSE);
  
  //button_messagebox_cancel := BtnCreate(closeBkPanel.Handle, 293, 150, 76, 28, ExpandConstant('{tmp}\button_cancel.png'), 0, FALSE);
  //BtnSetEvent(button_messagebox_cancel, ID_BUTTON_ON_CLICK_EVENT, WrapBtnCallback(@button_messagebox_cancel_on_click, 1));
  //BtnSetVisibility(button_messagebox_cancel, FALSE);
  //SetWindowLong(messagebox_close.Handle, GCL_STYLE, GetClassLong(messagebox_close.Handle, GCL_STYLE) or CS_DROPSHADOW);
  ImgApplyChanges(closeBkPanel.Handle);
END;

//释放需要的临时资源文件
PROCEDURE extract_temp_files();
BEGIN
  ExtractTemporaryFile('button_close.png');
  ExtractTemporaryFile('button_minimize.png');
  ExtractTemporaryFile('install_right_now.png');
  ExtractTemporaryFile('install_right_now_1.png');
  ExtractTemporaryFile('run_now.png');
  ExtractTemporaryFile('bk_white2.png');
  ExtractTemporaryFile('version_bk.png');
  ExtractTemporaryFile('messagebox_bk.png');
  ExtractTemporaryFile('button_customize_setup_1.png');
  ExtractTemporaryFile('btn_more_options_open_1.png');
  ExtractTemporaryFile('button_browse.png');
  ExtractTemporaryFile('progressbar_background.png');
  ExtractTemporaryFile('progressbar_foreground.png');
  ExtractTemporaryFile('checkbox_license.png');
  ExtractTemporaryFile('button_cancel.png');
  ExtractTemporaryFile('button_ok.png');
  ExtractTemporaryFile('button_yes.png');
  ExtractTemporaryFile('button_no.png');
  ExtractTemporaryFile('button_continue.png');
  ExtractTemporaryFile('button_teminate.png'); 
END;

// 初始化UI变量
procedure InitData();
begin
	isFirst := TRUE;
	is_installer_initialized := TRUE;
	is_wizardform_show_normal := TRUE;
	is_wizardform_released := FALSE;
	determine_wether_is_windows_7_or_not();
	extract_temp_files();
	WizardForm.InnerNotebook.Hide();
	WizardForm.OuterNotebook.Hide();
	WizardForm.Bevel.Hide();
  dNeedSpaceByte := {#MyAppNeedSpaceByte}
end;

// 初始化UI变量
procedure InitUI();
var temp1,temp2: String;
var Version1,Version2,Version3: String;
var hInst: longword;
var result222: integer;
BEGIN
	// 初始化主窗口
	with WizardForm do
	begin	
		BorderStyle := bsNone;
		Position := poScreenCenter;
		Width := WIZARDFORM_WIDTH_NORMAL;
		Height := WIZARDFORM_HEIGHT_MORE;
		Color := $FCD6BD;
		NextButton.Height := 0;
		CancelButton.Height := 0;
		BackButton.Visible := FALSE;
	end;
	
	// 初始化主窗口背景 ------------>
	mainBkPanel := TPanel.Create(WizardForm);
  with mainBkPanel do
  begin
    Parent := WizardForm;
    Top := WIZARDFORM_BORDER_WIDTH;
    Left := WIZARDFORM_BORDER_WIDTH;
    Width := WIZARDFORM_WIDTH_NORMAL - WIZARDFORM_BORDER_WIDTH * 2;
    Height := WIZARDFORM_HEIGHT_MORE - WIZARDFORM_BORDER_WIDTH * 2;
    BorderStyle := bsNone
    BevelKind := bkNone;
    BevelInner := bvNone;
    BevelOuter := bvNone;
    Visible := True;
  end;
	image_wizardform_background := ImgLoad(mainBkPanel.Handle, ExpandConstant('{tmp}\bk_white2.png'), 0, 0, WIZARDFORM_WIDTH_NORMAL, WIZARDFORM_HEIGHT_MORE, FALSE, TRUE);
	ImgApplyChanges(mainBkPanel.Handle);
	ImgApplyChanges(WizardForm.Handle);
  //<--------------------------------------------
	
	// 主窗口背景点击事件
	label_wizardform_main := TLabel.Create(mainBkPanel);
	with label_wizardform_main do
	begin
		Parent := mainBkPanel;
		AutoSize := FALSE;
		Left := 0;
		Top := 0;
		Width := mainBkPanel.Width;
		Height := mainBkPanel.Height;
		Caption := '';
		Transparent := TRUE;
		OnMouseDown := @wizardform_on_mouse_down;
	end;
	
	// 版本显示标签  ---------->
	image_version_background := ImgLoad(mainBkPanel.Handle, ExpandConstant('{tmp}\version_bk.png'), 456, 226, 41, 19, TRUE, TRUE);
	label_version := TLabel.Create(mainBkPanel);
	temp1 := '{#MyAppVersion}';
  Version1 := Copy(temp1, 1, Pos('.', temp1) - 1);
	temp1 := Copy(temp1, Pos('.', temp1) + 1, Length(temp1));
  Version2 := Copy(temp1, 1, Pos('.', temp1) - 1);
	temp1 := Copy(temp1, Pos('.', temp1) + 1, Length(temp1));
  Version3 := Copy(temp1, 1, Pos('.', temp1) - 1);
	temp2 := Version1 + '.' + Version2 + '.' + Version3
	
	with label_version do
	begin
		Parent := mainBkPanel;
		Caption := temp2;
		Transparent := true;
		Font.Size:= 9
		Font.Name:='微软雅黑'
		Font.Color:=$FFFFFF
		Left := 456 + 6;
		Top := 226 + 1;
		Width := 41;
		Height := 19;
		AutoSize := FALSE;	
	end;
  //<------------------------------------------------
	
	// 磁盘空间判断等label
	label_need_space := TLabel.Create(mainBkPanel);
	with label_need_space do
	begin
		Parent := mainBkPanel;
		Caption := '';
		Transparent := true;
		Font.Size:= 11
		Font.Name:='微软雅黑'
		Font.Color:=$808080
		Left := 40;
		Top := 491;
	end;

	label_disk_space := TLabel.Create(mainBkPanel);
	with label_disk_space do
	begin
		Parent := mainBkPanel;
		Caption := '';
		Transparent := true;
		Font.Size:= 11
		Font.Name:='微软雅黑'
		Font.Color:=$808080
		Left := 377;
		Top := 491;
	end;
  
	label_warn_tips := TLabel.Create(mainBkPanel);
	with label_warn_tips do
	begin
		Parent := mainBkPanel;
		Caption := '';
		Transparent := true;
		Font.Size:= 10
		Font.Name:='微软雅黑'
		Font.Color:=$4F4DFF
		Left := 40;
		Top := 558;
		Hide();
	end;
    
	// 内存等错误tips
	label_error_tips := TLabel.Create(mainBkPanel);
	with label_error_tips do
	begin
    Parent := mainBkPanel;
    AutoSize := FALSE;
    Left := 85;
    Top := 449;
    Width := 200;
    Height := 20;
    Font.Name := 'Microsoft YaHei';
    Font.Size := 9;
    Font.Color := clGray;
    Caption := '软件已经安装，不允许更换目录。';
    Transparent := TRUE;
    OnMouseDown := @wizardform_on_mouse_down;
    Hide();
	end;
	
	// 路径设置
	edit_target_path:= TEdit.Create(mainBkPanel);
    with edit_target_path do
	begin
		Parent := mainBkPanel;
		Text := WizardForm.DirEdit.Text;
		Font.Name := 'Microsoft YaHei';
		Font.Size := 12;
		Font.Color := $291c14;
		BorderStyle := bsNone;
		SetBounds(50,529,435,22);
		OnChange := @edit_target_path_on_change;
		Color := $FFFFFF;
		TabStop := FALSE;
	end;
	edit_target_path.Hide();
	
	// 主界面最大化和最小化按钮
	button_close := BtnCreate(mainBkPanel.Handle, 629, 3, 28, 28, ExpandConstant('{tmp}\button_close.png'), 0, FALSE);
	BtnSetEvent(button_close, ID_BUTTON_ON_CLICK_EVENT, WrapBtnCallback(@button_close_on_click, 1));
	button_minimize := BtnCreate(mainBkPanel.Handle, 591, 3, 28, 28, ExpandConstant('{tmp}\button_minimize.png'), 0, FALSE);
	BtnSetEvent(button_minimize, ID_BUTTON_ON_CLICK_EVENT, WrapBtnCallback(@button_minimize_on_click, 1));
	
	// 进度条
	label_install_progress := TLabel.Create(mainBkPanel);
    WITH label_install_progress DO
    BEGIN
      Parent := mainBkPanel;
      AutoSize := FALSE;
      Left := 258;
      Top := 343;
      Width := 200;
      Height := 31;
      Font.Name := 'Microsoft YaHei';
      Font.Size := 16;
      Font.Color := $FF8639;
      Caption := '';
      Transparent := TRUE;
      OnMouseDown := @wizardform_on_mouse_down;
    END;
	PBOldProc := SetWindowLong(WizardForm.ProgressGauge.Handle, -4, PBCallBack(@PBProc, 4));
	image_progressbar_background := ImgLoad(mainBkPanel.Handle, ExpandConstant('{tmp}\progressbar_background.png'), 55,315, 550, 4, FALSE, TRUE);
    image_progressbar_foreground := ImgLoad(mainBkPanel.Handle, ExpandConstant('{tmp}\progressbar_foreground.png'), 55, 315, 0, 0, TRUE, TRUE);
	ImgSetVisibility(image_progressbar_background, FALSE);
    ImgSetVisibility(image_progressbar_foreground, FALSE);
	
	// 立即安装按钮自定义 ---->
	button_install_now := BtnCreate(mainBkPanel.Handle, 238, 315, 214, 51, ExpandConstant('{tmp}\install_right_now_1.png'), 0, FALSE);
  BtnSetText(button_install_now, 'Install Now');//按钮文字
  //文字字体
  button_install_now_font := TFont.Create;
  with button_install_now_font do begin
      Size := 18;
      Name := '微软雅黑';
      Color := $000000;
  end;
  //应用字体
  BtnSetFont(button_install_now, button_install_now_font.Handle);
  BtnSetFontColor(button_install_now, $000000, $000000, $000000, $000000);
	BtnSetEvent(button_install_now, ID_BUTTON_ON_CLICK_EVENT, WrapBtnCallback(@install_right_now_on_click, 1));
  BtnSetEnabled(button_install_now, FALSE);
  //<------------------

	// 浏览
	button_browse := BtnCreate(mainBkPanel.Handle, 520, 520, 90, 38, ExpandConstant('{tmp}\button_browse.png'), 0, FALSE);
	BtnSetEvent(button_browse, ID_BUTTON_ON_CLICK_EVENT, WrapBtnCallback(@button_browse_on_click, 1));
	BtnSetVisibility(button_browse, FALSE);
	
  // 更多选择下拉选项 ------>
	button_customize_setup := BtnCreate(mainBkPanel.Handle, 268, 435, 120, 24, ExpandConstant('{tmp}\button_customize_setup_1.png'), 0, FALSE);
  BtnSetText(button_customize_setup, 'More Options');//按钮文字
  //文字字体
  button_customize_setup_font := TFont.Create;
  with button_customize_setup_font do begin
      Size := 10;
      Name := '微软雅黑';
      Color := $FF8639;
  end;
  //应用字体
  BtnSetFont(button_customize_setup, button_customize_setup_font.Handle);
  BtnSetFontColor(button_customize_setup, $FF8639, $FF8639, $FF8639, $FF8639);
	BtnSetEvent(button_customize_setup, ID_BUTTON_ON_CLICK_EVENT, WrapBtnCallback(@button_customize_setup_on_click, 1));
  //<------------------------
	
  // 非自定义设置
	button_uncustomize_setup := BtnCreate(mainBkPanel.Handle, 268, 435, 120, 24, ExpandConstant('{tmp}\btn_more_options_open_1.png'), 0, FALSE);
	BtnSetEvent(button_uncustomize_setup, ID_BUTTON_ON_CLICK_EVENT, WrapBtnCallback(@button_customize_setup_on_click, 1));
	BtnSetVisibility(button_uncustomize_setup, FALSE);

	// 许可证复选框  --------->  
	checkbox_license := BtnCreate(mainBkPanel.Handle, 117, 392, 16, 16, ExpandConstant('{tmp}\checkbox_license.png'), 0, TRUE);
	BtnSetEvent(checkbox_license, ID_BUTTON_ON_CLICK_EVENT, WrapBtnCallback(@checkbox_license_on_click, 1));
	BtnSetChecked(checkbox_license, FALSE);
  	// 阅读和同意title
	label_agree_title := TLabel.Create(mainBkPanel);
	with label_agree_title do
	begin
		Parent := mainBkPanel;
		AutoSize := FALSE;
		Left := 137;
		Top := 390;
		Width := 188;
		Height := 21;
		Caption := 'I have read and agree to';
		Font.Name := 'Microsoft YaHei';
		Font.Size := 12;
		Font.Color := $291c14;
		Transparent := TRUE;
	end;

	// 条款
	label_agree_content := TLabel.Create(mainBkPanel);
	with label_agree_content do
	begin
		Parent := mainBkPanel;
		AutoSize := FALSE;
		Left := 328;
		Top := 390;
		Width := 250;
		Height := 21;
		Caption := '《The User License Agreement》';
		Font.Name := 'Microsoft YaHei';
		Font.Size := 12;
		Font.Color := $FF8639;
		Transparent := TRUE;
		OnMouseDown := @button_license_on_click;
		Cursor := crHand;
	end;
  //<----------------------------------------------------

	// run now 
	button_run_now := BtnCreate(mainBkPanel.Handle, 238, 315, 214, 51, ExpandConstant('{tmp}\run_now.png'), 0, FALSE);
	BtnSetEvent(button_run_now, ID_BUTTON_ON_CLICK_EVENT, WrapBtnCallback(@run_now_on_click, 1));
	BtnSetVisibility(button_run_now, FALSE);
	
	ImgApplyChanges(mainBkPanel.Handle);
	ImgApplyChanges(WizardForm.Handle);
	
	// 消息关闭窗口
	messagebox_close_create();
end;

//重载安装程序初始化函数，判断是否已经安装新版本，是则禁止安装
FUNCTION InitializeSetup() : BOOLEAN;
BEGIN
  //languageName := ActiveLanguage();
  //if 'cn' = languageName then
  //begin
    
  //end 
	Result:=true;  
END;


//重载安装程序初始化函数（和上边那个不一样），进行初始化操作
procedure InitializeWizard();
begin
	InitData();
	InitUI();
end;

//安装程序销毁时会调用这个函数
PROCEDURE DeinitializeSetup();
BEGIN
	release_installer();
	ExitProcess(0);
END;

//安装页面改变时会调用这个函数
PROCEDURE CurPageChanged(CurPageID : INTEGER);
BEGIN
  IF (CurPageID = wpWelcome) THEN
  BEGIN
    mainBkPanel.Height := WIZARDFORM_HEIGHT_NORMAL - WIZARDFORM_BORDER_WIDTH * 2;
    WizardForm.Height := WIZARDFORM_HEIGHT_NORMAL;
  END;
  IF (CurPageID = wpInstalling) THEN
  BEGIN  
	is_wizardform_show_normal := TRUE;
	label_warn_tips.Hide();
    edit_target_path.Hide();
	label_disk_space.Hide();
	label_need_space.Hide();
    BtnSetVisibility(button_browse, FALSE);
	BtnSetVisibility(button_customize_setup, FALSE);
    BtnSetVisibility(button_uncustomize_setup, FALSE);
	BtnSetVisibility(checkbox_license, FALSE);
	label_agree_title.Hide();
	label_agree_content.Hide();
	BtnSetVisibility(button_install_now, FALSE);
	ImgSetVisibility(image_progressbar_background, TRUE);
    ImgSetVisibility(image_progressbar_foreground, TRUE);	
	mainBkPanel.Height := WIZARDFORM_HEIGHT_NORMAL - WIZARDFORM_BORDER_WIDTH * 2;
    WizardForm.Height := WIZARDFORM_HEIGHT_NORMAL;
	ImgApplyChanges(mainBkPanel.Handle);
    //BtnSetPosition(button_minimize, 570, 0, 30, 30); 
  END;
  IF (CurPageID = wpFinished) THEN
  BEGIN
    label_install_progress.Caption := '';
    label_install_progress.Visible := FALSE;
    ImgSetVisibility(image_progressbar_background, FALSE);
    ImgSetVisibility(image_progressbar_foreground, FALSE);
	BtnSetVisibility(button_install_now, FALSE);
    //BtnSetPosition(button_minimize, 540, 0, 30, 30);
    //BtnSetVisibility(button_close, TRUE);
	BtnSetVisibility(button_run_now, TRUE);
    BtnSetEvent(button_run_now, ID_BUTTON_ON_CLICK_EVENT, WrapBtnCallback(@run_now_on_click, 1));
    BtnSetEvent(button_close, ID_BUTTON_ON_CLICK_EVENT, WrapBtnCallback(@run_now_on_click, 1));
	ImgApplyChanges(mainBkPanel.Handle);
  END;
END;


function StrSplit(Text: String; Separator: String): TArrayOfString;
var
  i, p: Integer;
  Dest: TArrayOfString;
begin
  i := 0;
  repeat
    SetArrayLength(Dest, i+1);
    p := Pos(Separator,Text);
    if p > 0 then begin
      Dest[i] := Copy(Text, 1, p-1);
      Text := Copy(Text, p + Length(Separator), Length(Text));
      i := i + 1;
    end else begin
      Dest[i] := Text;
      Text := '';
    end;
  until Length(Text)=0;
  Result := Dest
end;

function RegisterSuffix(const Section, Key, Default, Filename: String): Boolean;
var
customSuffixArray: TArrayOfString;
suffix:String;
index:Integer;
begin
  suffix := GetIniString(Section, Key, Default, Filename);
  customSuffixArray := StrSplit(suffix, ',');
  for index:=0 to GetArrayLength(customSuffixArray)-1 do
  begin
    RegWriteStringValue(HKEY_CLASSES_ROOT, '.' + customSuffixArray[index], '', 'PhotonWorkShop');
  end;
	Result := true;
end;

procedure ChangeUninstallString;
var
  sUnInstPath: String;
  sUnInstallString: String;
  uicmd:String;
begin
  sUnInstPath := PRODUCT_REGISTRY_KEY;
  sUnInstallString := 'UninstallString';

  if RegQueryStringValue(HKEY_LOCAL_MACHINE, sUnInstPath, sUnInstallString, uicmd) then
  begin
    RegWriteStringValue(HKEY_LOCAL_MACHINE, sUnInstPath, sUnInstallString, ExpandConstant('"{app}/unins000.exe"') + ' /verysilent /suppressmsgboxes /norestart');
  end
end;

//安装步骤改变时会调用这个函数
PROCEDURE CurStepChanged(CurStep : TSetupStep);
var
ErrorCode: Integer;
var
languageName: string;
uicmd:String;
begin
	if(CurStep=ssDone) then
	begin
    languageName := ActiveLanguage();
    if 'cn' = languageName then
    begin
      RegWriteDWordValue(HKEY_CURRENT_USER, 
                           'SOFTWARE\ANYCUBIC',
                           'language', 
                           1)
    end 
    else if 'en' = languageName then
    begin
      RegWriteDWordValue(HKEY_CURRENT_USER, 
                           'SOFTWARE\ANYCUBIC',
                           'language', 
                           0)
    end;
    begin
    RegisterSuffix('base_config', 'model_suffix', '', ExpandConstant('{app}/global_config.ini'));
    RegisterSuffix('base_config', 'slice_suffix', '', ExpandConstant('{app}/global_config.ini'));
    RegisterSuffix('base_config', 'scene_suffix', '', ExpandConstant('{app}/global_config.ini'));
    RegisterSuffix('base_config', 'custom_suffix', '', ExpandConstant('{app}/global_config.ini'));
    RegWriteStringValue(HKEY_CLASSES_ROOT, 'PhotonWorkShop', '', 'Program PhotonWorkShop');
    RegWriteStringValue(HKEY_CLASSES_ROOT, 'PhotonWorkShop\DefaultIcon', '', ExpandConstant('"{app}\{#MyAppExeName}",0'));
    RegWriteStringValue(HKEY_CLASSES_ROOT, 'PhotonWorkShop\shell\open\command', '', ExpandConstant('"{app}\{#MyAppExeName}" "%1"'));
    end;
    //ShellExec('open', ExpandConstant('{sys}\{#CmdName}'), ExpandConstant('cd /d {app}'), '', SW_HIDE, ewNoWait, ErrorCode);
	//ShellExec('open', ExpandConstant('{win}\{#ExeplorerName}'), ExpandConstant('{app}\{#MyAppExeName}'), '', SW_SHOWNORMAL, ewNoWait, ErrorCode);
	//ShellExec('open', ExpandConstant('{app}\{#MyAppExeName}'),'','', SW_SHOWNORMAL, ewNoWait, ErrorCode);
   if RegQueryStringValue(HKEY_CURRENT_USER, 
                           'SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers',
                           ExpandConstant('{app}\{#MyAppExeName}'), 
                           uicmd) then
    begin
      RegDeleteValue(HKEY_CURRENT_USER, 'SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers', ExpandConstant('{app}\{#MyAppExeName}'));
    end; 
    ChangeUninstallString();  
	ShellExec('open', ExpandConstant('{app}\Install.bat'), ExpandConstant('.\{#MyAppExeName}'), '', SW_HIDE, ewNoWait, ErrorCode);	
	end;
END;

//指定跳过哪些标准页面
FUNCTION ShouldSkipPage(PageID : INTEGER) : BOOLEAN;
BEGIN
  IF (PageID = wpLicense) THEN Result := TRUE;
  IF (PageID = wpPassword) THEN Result := TRUE;
  IF (PageID = wpInfoBefore) THEN Result := TRUE;
  IF (PageID = wpUserInfo) THEN Result := TRUE;
  IF (PageID = wpSelectDir) THEN Result := TRUE;
  IF (PageID = wpSelectComponents) THEN Result := TRUE;
  IF (PageID = wpSelectProgramGroup) THEN Result := TRUE;
  IF (PageID = wpSelectTasks) THEN Result := TRUE;
  IF (PageID = wpReady) THEN Result := TRUE;
  IF (PageID = wpPreparing) THEN Result := TRUE;
  IF (PageID = wpInfoAfter) THEN Result := TRUE;
END;

//卸载步骤改变时会调用此函数
PROCEDURE CurUninstallStepChanged(CurUninstallStep : TUninstallStep);
BEGIN
  IF (CurUninstallStep = usAppMutexCheck) THEN
  BEGIN
    //此阶段为检查应用程序互斥的阶段，请在此进行互斥操作
  END;
END;


function InitializeUninstall(): Boolean;
var ErrorCode: INTEGER;
begin
	ShellExec('open', ExpandConstant('"{app}/uninstall.exe"'), '', '', SW_HIDE, ewNoWait, ErrorCode);	
	Result := FALSE;
end;
		
